<template>
    <div class="paper" id="paper"></div>
</template>
<script>
import dagre from "dagre";
import graphlib from "graphlib";
import { dia, shapes, layout } from "jointjs";
import svgPanZoom from 'svg-pan-zoom';
import '/node_modules/jointjs/dist/joint.css';

export default {
    data(){
        return {
            graph: null,
            paper: null,
            
            nodes: [
                { id: 1, label: 'node1' },
                { id: 2, label: 'node2' },
                { id: 3, label: 'node3' }
            ],
            
            links: [
                { from: 1, to: 2 },
                { from: 1, to: 3 }
            ],
            
            nodeList: [],
            
            linkList: [],
            
            currCell: null,
        }
    },
    methods: {
        init(){
            this.initGraph();
            this.createNode();
            this.createLink();
            this.randomLayout();
            this.svgPanZoom();
            this.paperEvent();
        },
        
        initGraph() {
            this.nodeList = [];
            this.linkList = [];
            let paper = document.getElementById('paper');
            this.graph = new dia.Graph();
            this.paper = new dia.Paper({
                dagre: dagre,
                graphlib: graphlib,
                el: paper,
                model: this.graph,
                width: '100%',
                height: 'calc(100vh - 100px)',
                background: {
                    color: '#f5f5f5'
                },
                drawGrid: true,
                gridSize: 20,
            });
        },
        
        createNode(){
            this.nodes.forEach(ele => {
                let node = new shapes.standard.Rectangle({
                    id: ele.id,
                    size: {
                        width: 100,
                        height: 50
                    },
                    attrs: {
                        body: {
                            fill: '#ddd',
                            stroke: 'none'
                        },
                        text: {
                            text: ele.label
                        }
                    }
                });
                this.nodeList.push(node);
            })
            this.graph.addCell(this.nodeList);
        },
        
        createLink(){
            this.links.forEach(ele => {
                let link = new shapes.standard.Link({
                    source: {
                        id: ele.from
                    },
                    target: {
                        id: ele.to
                    },
                    attrs: {
                        line: {
                            stroke: '#aaa',
                            strokeWidth: 1
                        }
                    }
                });
                this.linkList.push(link);
            })
            this.graph.addCell(this.linkList);
        },
        
        randomLayout(){
            layout.DirectedGraph.layout(this.graph, {
            dagre: dagre,
            graphlib: graphlib,
                
            rankDir: "LR",
                
            rankSep: 200,
                
            nodeSep: 80,
                
                edgeSep: 50
            });
        },
        
        svgPanZoom(){
            if(this.nodes.length){
                let svgZoom = svgPanZoom('#paper svg', {
                    
                    panEnabled: true,
                    
                    zoomEnabled: true,
                    
                    dblClickZoomEnabled: false,
                    
                    minZoom: 0.01,
                    
                    maxZoom: 100,
                    
                    fit: true,
                    
                    center: true,
                    
                    beforePan: (oldPan, newPan) => {
                        if(this.currCell){
                            return false;
                        }
                    }
                })
                svgZoom.setZoomScaleSensitivity(0.5);
                
                let {sx, sy} = this.paper.scale();
                if(sx > 1){
                    svgZoom.zoom(1/sx);
                } else {
                    svgZoom.zoom(0.9);
                }
            }
        },
        paperEvent(){
            this.paper.on('element:pointerdown', (cellView, evt, x, y) => {
                this.currCell = cellView;
            })
            this.paper.on('cell:pointerup blank:pointerup', (cellView, evt, x, y) => {
                this.currCell = null;
            })
        },
    },
    mounted(){
        this.init();
    }
}
</script>